
#include <BPlusTreeNodesStorage.hpp>
#include <FTSSException.hpp>
#include <stdio.h>
#include <Util.hpp>
#include <sys/types.h>
#include <fcntl.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
using namespace FTSS;

BPlusTreeNodeWordHash* BPlusTreeNodeStorage::GetNodeById(INT_32 node_id){
//	fprintf(stderr, "nodes_numeber=%d, length=%d",  length_data, length_stack);
	if (node_id < length_data){
		BPlusTreeNodeWordHash  *pRes = new BPlusTreeNodeWordHash(
							storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * node_id + 2],
							storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * node_id + 3],
							storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * node_id + 5]);
		if (storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * node_id + 4] != node_id){
			throw LogicException("Something wrong with B PLUS TREE node STORAGE\n");
		}
		pRes->node_id = node_id;
		return pRes;
	}
	return NULL;
}

INT_32 BPlusTreeNodeStorage::DumpNode(BPlusTreeNodeWordHash *pNode){
	fprintf(stderr, "pNode=(%lld,%lld,%lld) ", pNode->word_hash, pNode->chunk_number, pNode->size);
	INT_32 current_node_id;
	if (pNode->node_id != -1){
		current_node_id = pNode->node_id;
		if (current_node_id > length_data) length_data = current_node_id;
	} else if (length_stack > 0){
		current_node_id = vector_data_mmap[length_stack + 1];
		--length_stack;
	} else {
		current_node_id = length_data;
		++length_data;
	}
	//remmaping and increment filesize
	if ((sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * current_node_id + 5 ) >= size_storage_nodes / sizeof(INT_64)){
		fprintf(stderr,"need remmap\n");
		if (ReMMAP(data_storageHandler) != 0)
			throw UnixException(errno, "remmap nodes sotrage fails");
		fprintf(stderr,"newsizestoragenodes=%d\n",size_storage_nodes);
	}
	fprintf(stderr, "current_offset=%d ",sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) *  current_node_id + 5) ;
	fprintf(stderr, "size_storage_nodes=%d ", size_storage_nodes); 
	storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * current_node_id + 2] = pNode->word_hash;
	storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * current_node_id + 3] = pNode->chunk_number;
	storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * current_node_id + 4] = current_node_id;
	storage_data_mmap[sizeof(BPlusTreeNodeWordHash)/sizeof(UINT_64) * current_node_id + 5] = pNode->size;
	pNode->node_id = current_node_id;

	return current_node_id;
}

INT_32 BPlusTreeNodeStorage::DeleteNode(INT_32 node_id){
                 if (length_stack + 2 >= (size_vector_file / sizeof(INT_64))){
                         if (ReMMAP(vector_empty_blocksHandler) != 0)
                                 throw UnixException(errno, "remmap vector empty block fails");
                 }               
                 if (node_id < length_data){
                         vector_data_mmap[length_stack + 2] = node_id;
                         ++length_stack;
                         return 0;
                 }       
                return -1;
         }   



